package cn.iotnc.camera.ui.display

import android.content.Context
import android.net.Uri
import android.view.TextureView
import cn.iotnc.camera.BuildConfig
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.displayMetrics
import org.jetbrains.anko.info
import org.jetbrains.anko.warn
import org.videolan.libvlc.LibVLC
import org.videolan.libvlc.Media
import org.videolan.libvlc.MediaPlayer

fun LibVLC.vlcMedia(rtspUrl: String) = Media(this, Uri.parse(rtspUrl)).apply {
    setHWDecoderEnabled(false, false)
    addOption(":no-audio")
    addOption(":rtsp-tcp=true")
}

class VLCPlayer(val applicationContext: Context, val textureView: TextureView) : IVLCPlayer, AnkoLogger {
    private var isPause = false
    private val libVLC: LibVLC by lazy {
        val options = ArrayList<String>().apply {
            add(if (BuildConfig.DEBUG) "-vv" else "-v")
            //缓冲时间 10ms
            add("--network-caching=10")
            val opengl = -1 //OpenGL ES2 使用, 1开, 0关
            if (opengl == 1) add("--vout=gles2,none")
            else if (opengl == 0) add("--vout=android_display,none")

            //强制画面色度RV32/RV16/YV12, 默认是RGB 16-bit, YV12性能最佳
            add("--android-display-chroma")
            add("YV12")

            //去块滤镜设置, 不去块(最快)
            add("--avcodec-skiploopfilter")
            add("" + 4)
//            val frameSkip = true//加速解码,会降低画质
//            add("--avcodec-skip-frame")
//            add(if (frameSkip) "2" else "0")
//            add("--avcodec-skip-idct")
//            add(if (frameSkip) "2" else "0")
        }
        LibVLC(applicationContext, options)
    }
    private val mediaPlayer: MediaPlayer by lazy {
        MediaPlayer(libVLC)
    }

    override fun setListener(onLoading: () -> Unit, onSuccess: () -> Unit, onError: () -> Unit) {
        mediaPlayer.setEventListener {
            when (it.type) {
                MediaPlayer.Event.MediaChanged -> {
                    warn { "onEventChanged: MediaChanged..." }
                    onLoading()
                }
                MediaPlayer.Event.Opening -> {
                    warn { "onEventChanged: Opening..." }
                }
                MediaPlayer.Event.Buffering -> {
                    warn { "onEventChanged: Buffering ${it.buffering}" }
                }
                MediaPlayer.Event.Playing -> {
                    warn { "onEventChanged: Playing... pausable=${it.pausable}" }
                    if (!isPause) {
                        onLoading()
                    } else {
                        isPause = false
                    }
                }
                MediaPlayer.Event.Paused -> {
                    warn { "onEventChanged: Paused..." }
                    isPause = true
                }
                MediaPlayer.Event.Stopped -> warn { "onEventChanged: Stopped..." }
                MediaPlayer.Event.EndReached -> warn { "onEventChanged: EndReached..." }
                MediaPlayer.Event.EncounteredError -> {
                    warn { "onEventChanged: EncounteredError..." }
                    //stateLayout.showError("连接失败: 无法加载该视频", "重试")
                    onError()
                }
                MediaPlayer.Event.PositionChanged -> {
                    //warn { "positionChanged: ${it.positionChanged}" }
                }
                MediaPlayer.Event.TimeChanged -> {
                    //warn { "TimeChanged: ${it.timeChanged}" }
                }
                MediaPlayer.Event.SeekableChanged -> warn { "onEventChanged: SeekableChanged ${it.seekable}" }
                MediaPlayer.Event.PausableChanged -> warn { "onEventChanged: PausableChanged ${it.pausable}" }
                MediaPlayer.Event.LengthChanged -> warn { "onEventChanged: LengthChanged ${it.lengthChanged}" }
                MediaPlayer.Event.Vout -> {
                    warn { "onEventChanged: Vout ${it.voutCount}" }
                    //stateLayout.showContent()
                    //showContent()
                    onSuccess()
                }
                MediaPlayer.Event.ESAdded -> warn { "onEventChanged: ESAdded..." }
                MediaPlayer.Event.ESDeleted -> warn { "onEventChanged: ESDeleted..." }
                MediaPlayer.Event.ESSelected -> warn { "onEventChanged: ESSelected..." }
                else -> {
                    info { "onEventChanged: type = 0x${Integer.toHexString(it.type)}" }
                }
            }
        }
    }

    override fun playVideo(url: String) {
        if (mediaPlayer.isPlaying) {
            mediaPlayer.stop()
        }
        if (!mediaPlayer.vlcVout.areViewsAttached()) {
            mediaPlayer.vlcVout.apply {
                setVideoView(textureView)
                attachViews()
                val metrics = applicationContext.displayMetrics
                if (metrics.widthPixels.toFloat() / metrics.heightPixels > 16f / 9) {
                    setWindowSize((metrics.heightPixels * 16f / 9).toInt(), metrics.heightPixels)
                } else {
                    setWindowSize(metrics.widthPixels, (metrics.widthPixels * 9f / 16).toInt())
                }
            }
        }
        val vlcMedia = libVLC.vlcMedia(url)
        mediaPlayer.media = vlcMedia
        mediaPlayer.play()
        vlcMedia.release()
    }

    override fun play() {
        mediaPlayer.play()
    }

    override fun pause() {
        mediaPlayer.pause()
    }

    override fun stop() {
        mediaPlayer.stop()
    }

    override fun isPlaying(): Boolean = mediaPlayer.isPlaying

    override fun release() {
        mediaPlayer.setEventListener(null)
        mediaPlayer.vlcVout.detachViews()
        mediaPlayer.release()
    }

}